Skip to content

fix(darwin): fix vibevoice-cpp build linkage + fail-safe go backend packaging - #10276

Merged
mudler merged 2 commits into
masterfrom
fix/vibevoice-darwin-packaging
Jun 12, 2026
Merged

fix(darwin): fix vibevoice-cpp build linkage + fail-safe go backend packaging#10276
mudler merged 2 commits into
masterfrom
fix/vibevoice-darwin-packaging

Conversation

@localai-bot

@localai-bot localai-bot commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

What

Fixes #10267.

The darwin/arm64 vibevoice-cpp image shipped the source tree with a half-built CMake directory (build-libgovibevoicecpp-fallback.so/, a directory — not a .so) and no backend binary, so the backend could never start: run.sh exec'd a vibevoice-cpp binary that was not in the package, and LocalAI timed out waiting for the gRPC service.

Root cause (the actual build failure)

CI's darwin job surfaced it directly:

No rule to make target 'vibevoice/libvibevoice.a', needed by 'libgovibevoicecpp.so'.  Stop.

The upstream vibevoice project is added with add_subdirectory(... EXCLUDE_FROM_ALL), so its vibevoice static-library target is only built when something links it as a target. The Apple link branch in backend/go/vibevoice-cpp/CMakeLists.txt referenced only $<TARGET_FILE:vibevoice> — a bare archive path with no target reference — so CMake never emitted a rule to build libvibevoice.a. The Linux branch worked because it passes the vibevoice target name inside the --whole-archive flags.

Change

  1. backend/go/vibevoice-cpp/CMakeLists.txt — the real fix: on Apple, link the vibevoice target (establishes the build dependency) and apply -force_load as a separate link option to keep whole-archive semantics so purego can dlsym the vv_capi_* symbols.

  2. backend/go/vibevoice-cpp/Makefile — mirror whisper's cleanup discipline (make purge before each variant build, rm -rfv build* after) so a partial CMake tree can't survive into packaging.

  3. scripts/build/golang-darwin.sh — fail-safe packaging for every go darwin backend: before creating the OCI image, remove any stray build-* directory and assert the binary run.sh launches actually exists (derived from run.sh's exec $CURDIR/<binary> line — parakeet-cpp launches parakeet-cpp-grpc, so it isn't always ${BACKEND} — with a ${BACKEND} fallback). A build that produced no binary now fails the job loudly instead of publishing a source tree as a working backend.

Verification

Verified on the actual macOS arm64 CI runner: the Build vibevoice-cpp-darwin job now succeeds end to end (configure → compile ggml/metal/blas → build libvibevoice.a → link libgovibevoicecpp.so → go build → package). The first push of this PR (guard + Makefile only) correctly went red at the artifact check, proving the fail-safe; the linkage commit turned it green.

Assisted-by: Claude:claude-opus-4-8 [Claude Code]

mudler added 2 commits June 12, 2026 17:45
The darwin/arm64 vibevoice-cpp image shipped the source tree with a
half-built CMake directory (build-libgovibevoicecpp-fallback.so/) and no
backend binary, so the backend could never start: run.sh exec'd a
vibevoice-cpp binary that was not in the package and LocalAI timed out
waiting for the gRPC service.

Two durable, backend-agnostic defenses:

- backend/go/vibevoice-cpp/Makefile: mirror whisper's cleanup discipline so a
  partial CMake tree cannot survive into packaging. Run `make purge` before
  each variant build and `rm -rfv build*` after. The old recipe only removed
  its build dir after a successful `mv`, so a failed build left the half-built
  tree behind.

- scripts/build/golang-darwin.sh: before creating the OCI image, remove any
  stray build-* directory and assert that the binary run.sh launches actually
  exists. A build that produced no binary now fails the job loudly instead of
  publishing a source tree as a working backend. The binary name is derived
  from run.sh's `exec $CURDIR/<binary>` line (parakeet-cpp launches
  parakeet-cpp-grpc, so it is not always ${BACKEND}) with a ${BACKEND}
  fallback.

The underlying native build failure that left vibevoice-cpp half-built still
needs to be reproduced and fixed on Apple Silicon; this change ensures such a
failure can never again be published as a working image.

Refs #10267

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Assisted-by: Claude:claude-opus-4-8 [Claude Code]
…path)

The darwin build failed with:

    No rule to make target 'vibevoice/libvibevoice.a', needed by
    'libgovibevoicecpp.so'.  Stop.

The upstream vibevoice project is added with add_subdirectory(... EXCLUDE_FROM_ALL),
so its `vibevoice` static-library target is only built when something links it
as a target. The Apple branch linked only `$<TARGET_FILE:vibevoice>` - a bare
archive path with no target reference - so CMake never emitted a rule to build
libvibevoice.a, while the Linux branch worked because it passes the `vibevoice`
target name inside the --whole-archive flags.

Link the `vibevoice` target on Apple (establishing the build dependency) and
apply -force_load as a separate link option to keep whole-archive semantics so
purego can dlsym the vv_capi_* symbols.

Refs #10267

Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
Assisted-by: Claude:claude-opus-4-8 [Claude Code]
@localai-bot localai-bot changed the title fix(darwin): never package a go backend build tree as a working image fix(darwin): fix vibevoice-cpp build linkage + fail-safe go backend packaging Jun 12, 2026
@mudler
mudler merged commit cf71e29 into master Jun 12, 2026
74 of 75 checks passed
@mudler
mudler deleted the fix/vibevoice-darwin-packaging branch June 12, 2026 21:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

darwin/arm64 vibevoice-cpp backend image ships sources instead of build artifacts — backend cannot start

2 participants